Easy to use, Symbol-based enum implementation
Just list keys you need and enumerate
tag function will create an object with corresponding properties and unique values for your convenience.
Installation
Install with npm:
npm install @js-bits/enumerate
Install with yarn:
yarn add @js-bits/enumerate
Import where you need it:
import enumerate from '@js-bits/enumerate';
or require for CommonJS:
const enumerate = require('@js-bits/enumerate');
How to use
Example 1:
const { FOOT, METER } = enumerate`FOOT METER`;
const convertToFeet = (value, unit = FOOT) => {
if (unit === METER) {
return value * 3.281;
}
return value;
};
console.log(`${convertToFeet(5)} feet`);
console.log(`${convertToFeet(2, METER)} feet`);
Example 2:
const STAR_WARS = enumerate`I II III IV V VI`;
const getEpisodeName = episode => {
const { I, II, III, IV, V, VI } = STAR_WARS;
switch (episode) {
case I:
return 'The Phantom Menace';
case II:
return 'Attack of the Clones';
case III:
return 'Revenge of the Sith';
case IV:
return 'A New Hope';
case V:
return 'The Empire Strikes Back';
case VI:
return 'Return of the Jedi';
default:
return 'Unknown';
}
};
console.log(getEpisodeName(STAR_WARS.III));
console.log(getEpisodeName(STAR_WARS.IV));
console.log(getEpisodeName(STAR_WARS.X));
Primitive enum converters
By default enumerate
converts values to Symbols:
console.log(enumerate`FOOT METER`);
You can change this behavior by specifying an appropriate converter:
console.log(enumerate(String)`FOOT METER`);
console.log(enumerate(Number)`ZERO ONE TWO`);
const enumString = enumerate(String);
const enumNumber = enumerate(Number);
console.log(enumString`FOOT METER`);
console.log(enumNumber`ZERO ONE TWO`);
Advanced enum converters
There are several advanced converters also available.
const { LowerCase, UpperCase, Prefix, Increment } = enumerate;
console.log(enumerate(LowerCase)`
VALUE1
VALUE2
VALUE3
`);
console.log(enumerate(UpperCase)`
value1
value2
value3
`);
console.log(enumerate(Prefix('value|'))`x y z`);
console.log(enumerate('value|')`x y z`);
console.log(enumerate(Increment(10))`
VALUE1
VALUE2
VALUE3
`);
console.log(enumerate(10)`VALUE1 VALUE2 VALUE3`);
console.log(enumerate(Increment(10, 19))`
VALUE1
VALUE2
VALUE3
`);
Customization
Or you can implement your custom converter:
const customEnum = enumerate((acc, item) => {
acc[`-${item}-`] = `-${(Object.keys(acc).length + 1) * 10}-`;
return acc;
});
console.log(customEnum`
CODE1
CODE2
CODE3
`);
But remember that only default behavior guarantees global uniqueness of enumerated values.
enumerate.isEnum()
You can also check if the given object is a enum or not.
console.log(enumerate.isEnum({ a: 1, b: 2, c: 3 }));
console.log(enumerate.isEnum(enumerate`a b c`));
Type-safety and IntelliSense (code completion)
The package includes a TypeScript Declaration File and supports VS Code IntelliSense features.
But there is one caveat. In order to achieve full type safety you have to use a bit different syntax. Unfortunately.
So, instead of using enumerate()
directly as a tag function you can use enumerate.ts()
function.
Compare
versus
For example
enumerate.ts('ZERO ONE TWO', Number);
does exactly the same as
enumerate(Number)`ZERO ONE TWO`;
but it allows TypeScript to recognize the result type.
The reason of why we cannot use enumerate
directly is that there is a long-standing TypeScript issue with TemplateStringArray being incorrectly typed and, as result, not being able to be parameterized.
Notes
- Be careful adding new items to an existing numeric enum. Always append them to the end of the list to avoid changing previous item values.
- Requires TypeScript 4.8+ for best type safety features support.